"""
串口通信模块

该模块提供了用于UART串口通信的类和方法。通过使用这些类和方法，可以轻松实现串口数据的发送和接收，并支持简单的协议解析。

模块包含以下类：
- Serial: 提供了UART串口初始化、数据发送、数据接收、协议解析、缓冲区清空和串口关闭的功能。

示例用法：
uart = Serial(uart_num=2, baudrate=115200, tx_pin=17, rx_pin=16)  # 初始化UART串口，编号为2，波特率为115200，发送引脚为GPIO17，接收引脚为GPIO16

onled = [45,60,12,34,54,60,60,1,62]  # 定义LED开启的数据包
offled = [60,2,62]  # 定义LED关闭的数据包

def timer_callback(self):
    uart.timer_callback()  # 定时器回调函数，用于处理串口数据的接收和发送

timer = Timer(0)
timer.init(period=1, mode=Timer.PERIODIC, callback=timer_callback)  # 初始化定时器，周期为1ms，模式为周期性触发

while True:
    if len(uart.txBuff)==0:  # 如果发送缓冲区为空
        uart.txBuff.append(onled)  # 添加LED开启数据包到发送缓冲区
        uart.txBuff.append(onled)
        uart.txBuff.append(offled)  # 添加LED关闭数据包到发送缓冲区
    utime.sleep(0.5)  # 主程序休眠0.5秒

作者: XSP
创建日期: 2025年4月5日
版本: 1.0.0
"""

from machine import UART,Timer
import utime

class Serial:
    def __init__(self, uart_num=2, baudrate=115200, tx_pin=17, rx_pin=16):
        """
        初始化UART串口
        :param uart_num: UART编号 (1或2)
        :param baudrate: 波特率 (默认115200)
        :param tx_pin: 发送引脚 (默认GPIO17)
        :param rx_pin: 接收引脚 (默认GPIO16)
        """
        self.uart_num = uart_num
        self.baudrate = baudrate
        self.headflag = False
        self.tailflag = False
        self.txBuff   = []
        self.packlist = []
        self.tx_pin = tx_pin
        self.rx_pin = rx_pin
        
        # 初始化UART
        self.uart = UART(uart_num, baudrate=baudrate, tx=tx_pin, rx=rx_pin)

    def sendMsg(self):
        """
        发送数据
        :param data: 要发送的数据 (字符串或字节)
        :return: 发送的字节数
        """
        if len(self.txBuff)>0:
            self.uart.write(bytes(self.txBuff.pop(0)))
    
    def receiveMsg(self):
        """
        接收数据
        :param max_bytes: 最大接收字节数
        :return: 接收到的数据 (字节) 或 None (如果超时)
        """
        while self.uart.any():
            self.protocolAnalysis(self.uart.read(1))
            
    def timer_callback(self):
        self.receiveMsg()
        self.sendMsg()
        
    def flush(self):
        """清空输入缓冲区"""
        while self.uart.any():
            self.uart.read()
    
    def close(self):
        """关闭串口"""
        self.uart.deinit()
    
    def __del__(self):
        """析构函数，确保串口被关闭"""
        self.close()
        
    def protocolAnalysis(self, listdata):
        if self.headflag == False:
            #查找包头
            if listdata == b'\x3c':
                self.packlist = []
                self.packlist.append(listdata)
                self.headflag = True
        else:
            #包尾没找到时
            if self.tailflag == False:
                #包尾被找到
                if listdata == b'\x3e':
                    self.tailflag = True
                    self.packlist.append(listdata)
                    #print(self.packlist)
                else:
                    if listdata == b'\x3c':
                        self.packlist = []
                        self.packlist.append(listdata)
                        self.headflag = True
                    else:
                        self.packlist.append(listdata)

        if self.headflag == True and self.tailflag == True:
            if self.packlist[1] == b'\x01':
                print("led on")
            elif self.packlist[1] == b'\x02':
                print("led off")
            self.packlist = []
            self.headflag = False
            self.tailflag = False
                 
        
# 使用示例
if __name__ == "__main__":
    uart = Serial(uart_num=2, baudrate=115200, tx_pin=17, rx_pin=16)
    onled = [45,60,12,34,54,60,60,1,62]
    offled = [60,2,62]

    def timer_callback(self):
        uart.timer_callback()
        
    timer = Timer(0)
    timer.init(period=1, mode=Timer.PERIODIC, callback=timer_callback)
    # 发送数据
    while True:
        if len(uart.txBuff)==0:
            uart.txBuff.append(onled)
            uart.txBuff.append(onled)
            uart.txBuff.append(offled)
        utime.sleep(0.5)

        

